home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / hplip / base / logger.py < prev    next >
Text File  |  2008-10-13  |  12KB  |  353 lines

  1. # -*- coding: utf-8 -*-
  2. #
  3. # (c) Copyright 2002-2008 Hewlett-Packard Development Company, L.P.
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18. #
  19. # Authors: Doug Deprenger, Don Welch
  20. #
  21.  
  22. # Std Lib
  23. import sys
  24. import thread # TODO: Use threading instead (thread deprecated in Python 3.0)
  25. import syslog
  26. import traceback
  27. import string
  28. import os
  29.  
  30. identity = string.maketrans('','')
  31. unprintable = identity.translate(identity, string.printable)
  32.  
  33. def printable(s):
  34.     return s.translate(identity, unprintable)
  35.  
  36. DEFAULT_LOG_LEVEL = 'info'
  37.  
  38. class Logger(object):
  39.     LOG_LEVEL_NONE = 99
  40.     #LOG_LEVEL_INFO = 50
  41.     LOG_LEVEL_FATAL = 40
  42.     LOG_LEVEL_ERROR = 30
  43.     LOG_LEVEL_WARN = 20
  44.     LOG_LEVEL_INFO = 10
  45.     LOG_LEVEL_DEBUG3 = 3
  46.     LOG_LEVEL_DBG3 = 3
  47.     LOG_LEVEL_DEBUG2 = 2
  48.     LOG_LEVEL_DBG2 = 2
  49.     LOG_LEVEL_DEBUG = 1
  50.     LOG_LEVEL_DBG = 1
  51.  
  52.     logging_levels = {'none' : LOG_LEVEL_NONE,
  53.                        'fata' : LOG_LEVEL_FATAL,
  54.                        'fatal' : LOG_LEVEL_FATAL,
  55.                        'erro' : LOG_LEVEL_ERROR,
  56.                        'error' : LOG_LEVEL_ERROR,
  57.                        'warn' : LOG_LEVEL_WARN,
  58.                        'info' : LOG_LEVEL_INFO,
  59.                        'debug' : LOG_LEVEL_DEBUG,
  60.                        'dbg'  : LOG_LEVEL_DEBUG,
  61.                        'debug2' : LOG_LEVEL_DEBUG2,
  62.                        'dbg2' : LOG_LEVEL_DEBUG2,
  63.                        'debug3' : LOG_LEVEL_DEBUG3,
  64.                        'dbg3' : LOG_LEVEL_DEBUG3,
  65.                        }
  66.  
  67.     LOG_TO_DEV_NULL = 0
  68.     LOG_TO_CONSOLE = 1
  69.     LOG_TO_SCREEN = 1
  70.     LOG_TO_FILE = 2
  71.     LOG_TO_CONSOLE_AND_FILE = 3
  72.     LOG_TO_BOTH = 3
  73.  
  74.     # Copied from Gentoo Portage output.py
  75.     # Copyright 1998-2003 Daniel Robbins, Gentoo Technologies, Inc.
  76.     # Distributed under the GNU Public License v2
  77.     codes={}
  78.     codes["reset"]="\x1b[0m"
  79.     codes["bold"]="\x1b[01m"
  80.  
  81.     codes["teal"]="\x1b[36;06m"
  82.     codes["turquoise"]="\x1b[36;01m"
  83.  
  84.     codes["fuscia"]="\x1b[35;01m"
  85.     codes["purple"]="\x1b[35;06m"
  86.  
  87.     codes["blue"]="\x1b[34;01m"
  88.     codes["darkblue"]="\x1b[34;06m"
  89.  
  90.     codes["green"]="\x1b[32;01m"
  91.     codes["darkgreen"]="\x1b[32;06m"
  92.  
  93.     codes["yellow"]="\x1b[33;01m"
  94.     codes["brown"]="\x1b[33;06m"
  95.  
  96.     codes["red"]="\x1b[31;01m"
  97.     codes["darkred"]="\x1b[31;06m"
  98.  
  99.  
  100.     def __init__(self, module='', level=LOG_LEVEL_INFO, where=LOG_TO_CONSOLE_AND_FILE,
  101.                  log_datetime=False, log_file=None):
  102.                  
  103.         self._where = where
  104.         self._log_file = log_file
  105.         self._log_file_f = None
  106.         self._log_datetime = log_datetime
  107.         self._lock = thread.allocate_lock()
  108.         self.module = module
  109.         self.pid = os.getpid()
  110.         self.fmt = True
  111.         self.set_level(level)
  112.         
  113.     def set_level(self, level):
  114.         if isinstance(level, str):
  115.             level = level.lower()
  116.             if level in Logger.logging_levels.keys():
  117.                 self._level = Logger.logging_levels.get(level, Logger.LOG_LEVEL_INFO)
  118.                 return True
  119.             else:
  120.                 self.error("Invalid logging level: %s" % level)
  121.                 return False
  122.  
  123.         elif isinstance(level, int):
  124.             if Logger.LOG_LEVEL_DEBUG3 <= level <= Logger.LOG_LEVEL_FATAL:
  125.                 self._level = level
  126.             else:
  127.                 self._level = Logger.LOG_LEVEL_ERROR
  128.                 self.error("Invalid logging level: %d" % level)
  129.                 return False
  130.  
  131.         else:
  132.             return False
  133.  
  134.     def set_module(self, module):
  135.         self.module = module
  136.         self.pid = os.getpid()
  137.         
  138.     def no_formatting(self):
  139.         self.fmt = False
  140.  
  141.     def set_logfile(self, log_file):
  142.         self._log_file = log_file
  143.         try:
  144.             self._log_file_f = file(self._log_file, 'w')
  145.         except IOError:
  146.             self._log_file = None
  147.             self._log_file_f = None
  148.             self._where = Logger.LOG_TO_SCREEN
  149.             
  150.     def get_logfile(self):
  151.         return self._log_file
  152.  
  153.     def set_where(self, where):
  154.         self._where = where
  155.  
  156.     def get_level(self):
  157.         return self._level
  158.  
  159.     def is_debug(self):
  160.         return self._level <= Logger.LOG_LEVEL_DEBUG3
  161.  
  162.     level = property(get_level, set_level)
  163.  
  164.     def log(self, message, level):
  165.         if self._where in (Logger.LOG_TO_CONSOLE, Logger.LOG_TO_CONSOLE_AND_FILE):
  166.             try:
  167.                 self._lock.acquire()
  168.                 if level >= Logger.LOG_LEVEL_WARN:
  169.                     out = sys.stderr
  170.                 else:
  171.                     out = sys.stdout
  172.                 try:
  173.                     out.write(message)
  174.                 except UnicodeEncodeError:
  175.                     out.write(message.encode("utf-8"))
  176.  
  177.                 out.write('\n')
  178.             finally:
  179.                 self._lock.release()
  180.  
  181.     def log_to_file(self, message):
  182.         if self._log_file_f is not None:
  183.             try:
  184.                 self._lock.acquire()
  185.                 self._log_file_f.write(message.replace('\x1b', ''))
  186.                 self._log_file_f.write('\n')
  187.  
  188.             finally:
  189.                 self._lock.release()
  190.  
  191.     def stderr(self, message):
  192.         try:
  193.             self._lock.acquire()
  194.             sys.stderr.write("%s: %s\n" % (self.module, message))
  195.         finally:
  196.             self._lock.release()
  197.  
  198.     def debug(self, message): 
  199.         if self._level <= Logger.LOG_LEVEL_DEBUG:
  200.             txt = "%s[%d]: debug: %s" % (self.module, self.pid, message)
  201.             self.log(self.color(txt, 'blue'), Logger.LOG_LEVEL_DEBUG)
  202.  
  203.             if self._log_file is not None and \
  204.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  205.                 self.log_to_file(txt)
  206.  
  207.     dbg = debug
  208.  
  209.     def debug2(self, message): 
  210.         if self._level <= Logger.LOG_LEVEL_DEBUG2:
  211.             txt = "%s[%d]: debug2: %s" % (self.module, self.pid, message)
  212.             self.log(self.color(txt, 'blue'), Logger.LOG_LEVEL_DEBUG2)
  213.  
  214.             if self._log_file is not None and \
  215.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  216.                 self.log_to_file(txt)
  217.     dbg2 = debug2
  218.  
  219.     def debug3(self, message): 
  220.         if self._level <= Logger.LOG_LEVEL_DEBUG3:
  221.             txt = "%s[%d]: debug3: %s" % (self.module, self.pid, message)
  222.             self.log(self.color(txt, 'blue'), Logger.LOG_LEVEL_DEBUG3)
  223.  
  224.             if self._log_file is not None and \
  225.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  226.                 self.log_to_file(txt)
  227.     dbg3 = debug3
  228.  
  229.  
  230.     def debug_block(self, title, block):
  231.         if self._level <= Logger.LOG_LEVEL_DEBUG:
  232.             line = "%s[%d]: debug: %s:" % (self.module,  self.pid, title)
  233.             self.log(self.color(line, 'blue'), Logger.LOG_LEVEL_DEBUG)
  234.             self.log(self.color(block, 'blue'), Logger.LOG_LEVEL_DEBUG)
  235.  
  236.             if self._log_file is not None and \
  237.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  238.  
  239.                 self.log_to_file(line % (self.module, self.pid, title))
  240.                 self.log_to_file(block)
  241.  
  242.  
  243.     printable = """ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~  """
  244.  
  245.     def log_data(self, data, width=16): 
  246.         if self._level <= Logger.LOG_LEVEL_DEBUG:
  247.             if data:
  248.                 index, line = 0, data[0:width]
  249.                 while line:
  250.                     txt = ' '.join(['%04x: ' % index, ' '.join(['%02x' % ord(d) for d in line]), 
  251.                         ' '*(width*3-3*len(line)), ''.join([('.', i)[i in Logger.printable] for i in line])])
  252.     
  253.                     self.log(self.color("%s[%d]: debug: %s" % (self.module,  self.pid, txt), 'blue'), 
  254.                         Logger.LOG_LEVEL_DEBUG)
  255.     
  256.                     index += width
  257.                     line = data[index:index+width]
  258.             else:
  259.                 self.log(self.color("%s[%d]: debug: %s" % (self.module,  self.pid, "0000: (no data)"), 'blue'), 
  260.                         Logger.LOG_LEVEL_DEBUG)
  261.  
  262.     def info(self, message=''):
  263.         if self._level <= Logger.LOG_LEVEL_INFO:
  264.             self.log(message, Logger.LOG_LEVEL_INFO)
  265.  
  266.             if self._log_file is not None and \
  267.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  268.                 self.log_to_file("%s[%d]: info: :%s" % (self.module, self.pid, message))
  269.  
  270.     information = info
  271.  
  272.     def warn(self, message):
  273.         if self._level <= Logger.LOG_LEVEL_WARN:
  274.             txt = "warning: %s" % message.encode('utf-8')
  275.             self.log(self.color(txt, 'fuscia'), Logger.LOG_LEVEL_WARN)
  276.  
  277.             syslog.syslog(syslog.LOG_WARNING, "%s[%d]: %s" % (self.module, self.pid, txt))
  278.  
  279.             if self._log_file is not None and \
  280.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  281.                 self.log_to_file(txt)
  282.  
  283.     warning = warn
  284.  
  285.     def note(self, message):
  286.         if self._level <= Logger.LOG_LEVEL_WARN:
  287.             txt = "note: %s" % message
  288.             self.log(self.color(txt, 'green'), Logger.LOG_LEVEL_WARN)
  289.  
  290.             if self._log_file is not None and \
  291.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  292.                 self.log_to_file(txt)
  293.  
  294.     notice = note
  295.  
  296.     def error(self, message):
  297.         if self._level <= Logger.LOG_LEVEL_ERROR:
  298.             txt = "error: %s" % message.encode("utf-8")
  299.             self.log(self.color(txt, 'red'), Logger.LOG_LEVEL_ERROR)
  300.  
  301.             syslog.syslog(syslog.LOG_ALERT, "%s[%d]: %s" % (self.module, self.pid, txt))
  302.  
  303.             if self._log_file is not None and \
  304.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  305.                 self.log_to_file(txt)
  306.  
  307.  
  308.     def fatal(self, message):
  309.         if self._level <= Logger.LOG_LEVEL_FATAL:
  310.             txt = "fatal error: :%s" % self.module.encode('utf-8')
  311.             self.log(self.color(txt, 'red'), Logger.LOG_LEVEL_DEBUG)
  312.  
  313.             syslog.syslog(syslog.LOG_ALERT, "%s[%d]: %s" % (self.module, self.pid, txt))
  314.  
  315.             if self._log_file is not None and \
  316.                 self._where in (Logger.LOG_TO_FILE, Logger.LOG_TO_CONSOLE_AND_FILE):
  317.                 self.log_to_file(txt)
  318.  
  319.  
  320.     def exception(self):
  321.         typ, value, tb = sys.exc_info()
  322.         body = "Traceback (innermost last):\n"
  323.         lst = traceback.format_tb(tb) + traceback.format_exception_only(typ, value)
  324.         body = body + "%-20s %s" % (''.join(lst[:-1]), lst[-1],)
  325.         self.fatal(body)
  326.  
  327.     def color(self, text, color):
  328.         if self.fmt:
  329.             return ''.join([Logger.codes.get(color, 'bold'), text, Logger.codes['reset']])   
  330.         return text
  331.  
  332.     def bold(self, text):
  333.         return self.color(text, 'bold')
  334.  
  335.     def red(self, text):
  336.         return self.color(text, 'red')
  337.         
  338.     def green(self, text):
  339.         return self.color(text, 'green')
  340.         
  341.     def purple(self, text):
  342.         return self.color(text, 'purple')
  343.     
  344.     def yellow(self, text):
  345.         return self.color(text, 'yellow')
  346.    
  347.     def darkgreen(self, text):
  348.         return self.color(text, 'darkgreen') 
  349.       
  350.     def blue(self, text):
  351.         return self.color(text, 'blue')
  352.     
  353.